home *** CD-ROM | disk | FTP | other *** search
- /* (c) 1990 S.Hawtin.
- Permission is granted to copy this file provided
- 1) It is not used for commercial gain
- 2) This notice is included in all copies
- 3) Altered copies are marked as such
-
- No liability is accepted for the contents of the file.
-
- */
-
- /**********************************************************************/
-
- /*
- This is a short example program that selects a phrase from a file and
- prints it.
- */
-
- /* We are going to print stuff to files so we must have "stdio.h" */
- #include <stdio.h>
-
- /* Comment out this line to remove the speech bit */
- #define SPEAKING 1
-
- #ifdef SPEAKING
- /* The include files for the narrator device */
- #include <exec/ports.h>
- #include <devices/narrator.h>
- #endif
-
- /**********************************************************************/
-
- /* First a set of constants */
-
- /*
- The data file that all the phrases come from.
- This file must be at least MIN_LENGTH characters long, and have
- more than 3 phrases in.
- */
- #define MIN_LENGTH 100
- #define SRC_FILE "fortune.txt"
-
- /*
- Some special "characters", to indicate conditions other than
- normal characters read in from the file.
- */
- #define MY_EOF -1
- #define MY_EOL -2
-
- /* Some variables to control the program */
-
- /* A flag to tell us to be noisy so that we can see what is going on */
- static int noisy = 0;
-
- /* A flag to tell us not to use the narrator */
- static int silent = 0;
-
- /**********************************************************************/
-
- /* Some special NorthC things */
-
- #ifdef NORTHC
-
- /* This will be 0 if program was called from CLI */
- extern long _fromWB;
-
- /*
- The description of a console window to use if called from the
- workbench
- */
- char *_WBConsole="con:20/40/600/70/NorthC: Fortune Program";
-
- #endif
-
- /**********************************************************************/
-
- /* The functions */
-
- static int
- tyi(fptr)
- FILE *fptr;
- {/*
- Input a single character from the file, if we find the end of
- a phrase return MY_EOL, if we find the end of a file return MY_EOF.
- */
-
- /* Somewhere to keep the characters as they are read */
- int next;
-
- /* First get the next character from the file */
- next = fgetc(fptr);
-
- /*
- Now we have three special cases,
- 1) the '\' charcter: Read the next character without
- translating it. This lets us embed newlines in a phrase.
- 2) the newline charcter: Tell the caller we have got the
- end of the phrase.
- 3) the end of file: Tell the caller we have an end of file.
- */
- if(next=='\\')
- {next = fgetc(fptr);
- /* Translate some escape characters */
- if(next=='n')
- next = '\n';
- else if(next=='b')
- next = '\b';
- }
- else if(next=='\n')
- next = MY_EOL;
- else if (next==EOF || feof(fptr))
- next = MY_EOF;
- return(next);
- }
-
- #ifdef SPEAKING
- /* We are going to output the phrase through the narrator device */
-
- /* The audio channels we are going to use, these are from the
- Amiga ROM Kernel Reference Manual: Libraries and Devices
- I have no idea what they do */
- static BYTE audChanMasks[4] = {3,5,10,12};
-
- static void
- say(some_lines)
- char *some_lines[];
- {/* Use the speech device to output some lines of text */
-
- /* A function that returns a structure */
- extern struct MsgPort *CreatePort();
- extern void *OpenLibrary();
-
- /* Internal variables for the function */
- void *trans_lib;
- int count,retCount;
- char buffer[256];
- struct MsgPort *writeport = NULL;
- struct narrator_rb *writeNarrator = NULL;
-
- if(noisy)
- printf("\n");
-
- /* First open the translator library to translate the phrases */
- trans_lib = OpenLibrary("translator.library",0L);
- if(NULL==trans_lib)
- {
- if(noisy)
- printf("Cannot open translator library\n");
- return;
- }
-
- /* Now set up the structures to communicate with the narrator device */
- writeport = CreatePort(0,0);
- if(writeport==NULL)
- {
- if(noisy)
- printf("Cannot open ports\n");
- goto abort;
- }
- writeNarrator = (struct narrator_rb *)CreateExtIO(writeport,
- sizeof(struct narrator_rb));
- if(writeNarrator==NULL)
- {
- if(noisy)
- printf("Cannot create io blocks\n");
- goto abort;
- }
-
- /* Now set up the write message structures */
- writeNarrator->ch_masks = (audChanMasks);
- writeNarrator->nm_masks = sizeof(audChanMasks);
- writeNarrator->message.io_Data = (APTR)buffer;
- writeNarrator->message.io_Length = 256;
- writeNarrator->message.io_Command = CMD_WRITE;
-
- if(OpenDevice("narrator.device",0L,writeNarrator,0L)!=0)
- {
- if(noisy)
- printf("Cannot open narrator\n");
- goto abort;
- }
-
- /* Now go through the lines one at a time */
- for(count=0;some_lines[count];++count)
- {/* Say each line */
- retCount = 0;
- do {
- retCount = Translate(&some_lines[count][-retCount],
- retCount+strlen(some_lines[count]),buffer,256);
- if(noisy)
- printf("Say \"%s\"\n",buffer);
- writeNarrator->message.io_Length = strlen(buffer);
- if(SendIO(writeNarrator)!=NULL)
- {
- if(noisy)
- printf("Cannot do write!\n");
- goto abort;
- }
- WaitIO(writeNarrator);
- } while (retCount!=0);
- }
-
- /* No need to close the library NorthC will do it for us */
- CloseLibrary(trans_lib);
- CloseDevice(writeNarrator);
- abort:
- if(writeNarrator)
- DeleteExtIO(writeNarrator,sizeof(struct narrator_rb));
- if(writeport)
- DeletePort(writeport);
- }
- #endif
-
- static int
- find_next(fptr)
- FILE *fptr;
- {/*
- Keep reading until we find the end of the current phrase, when
- we have the end of phrase return true if we did not get the end
- of file as well.
- */
- int next;
-
- /* Need to do two reads to make sure we have not hit a '\n'
- in the middle of a multi line phrase */
- next = tyi(fptr);
- next = tyi(fptr);
- while(next!=MY_EOL && next!=MY_EOF)
- next = tyi(fptr);
- return(next!=MY_EOF);
- }
-
- #define LINE_LEN 128
- #define MAX_LINE 10
-
- static int
- out_next(fptr)
- FILE *fptr;
- {/*
- Output the next phrase to the terminal, this involves reading the
- phrase and outputting until we run out of characters.
- Again if we found the end of the file return false.
- */
- int next;
- #ifdef SPEAKING
- /* If sending stuff to the narrator we must keep track of what has been
- printed so far */
- char *phrase[MAX_LINE];
- int num_lines = 0;
- int curr_end;
-
- /* Where we build up the phrase for the speech device */
- phrase[0] = malloc(LINE_LEN);
- num_lines = 0;
- curr_end = 0;
- #endif
-
- next = tyi(fptr);
- while(next!=MY_EOL && next!=MY_EOF)
- {fputc(next,stdout);
-
- #ifdef SPEAKING
- /* Put the next character into the phrase buffer */
- if(phrase[num_lines])
- phrase[num_lines][curr_end++] = next;
- #endif
-
- /* Put four spaces at the start of each line */
- if(next=='\n')
- {puts(" ");
- #ifdef SPEAKING
- /* Add a new line on to the phrase */
- phrase[num_lines++][--curr_end] = '\0';
- curr_end = 0;
- phrase[num_lines] = malloc(LINE_LEN);
- #endif
- }
-
- /* Get the next charcter from the file */
- next = tyi(fptr);
- }
-
- #ifdef SPEAKING
- phrase[num_lines++][curr_end] = '\0';
- phrase[num_lines] = NULL;
-
- /* Flush the buffer to give the user a clue while the speech is
- going on */
- fflush(stdout);
-
- /* Go speak the phrase */
- if(!silent)
- say(phrase);
-
- /* Now free the space that we grabbed for the phrase */
- for(--num_lines;num_lines>=0;--num_lines)
- free(phrase[num_lines]);
- #endif
-
- return(next!=MY_EOF);
- }
-
- void
- main(argc,argv)
- int argc; /* Both arguments are unused in this example */
- char **argv;
- {/* Pick a single saying from a file and send it to the user */
- FILE *fptr; /* The data file */
- long length; /* The total length of the data file */
- long where; /* Where we are going to look for our phrase */
-
- /* Check the arguments */
- if(argc>1)
- {int i;
-
- for(i=1;i<argc;++i)
- {if(0==stricmp(argv[i],"noisy"))
- noisy = 1;
- else if(0==stricmp(argv[i],"silent"))
- silent = 1;
- }
- }
-
- /* First open the data file */
- fptr = fopen(SRC_FILE,"r");
-
- /* Check to make sure that we got it */
- if(fptr==NULL)
- {printf("Remember:\n\n A good user always keeps\n");
- printf(" \"%s\" with his fortune program\n",SRC_FILE);
- exit(20);
- }
-
- /*
- Seed the random number generator, use the current time as a
- good source of random numbers
- */
- srand(time(NULL));
-
- /* Find out how long the file is, first move to the end */
- fseek(fptr,0L,SEEK_END);
- /* Then ask where we now are */
- length = ftell(fptr);
-
- /*
- Check that the file is long enough, this is not really
- required but we might get problems with small files
- */
- if(length<MIN_LENGTH)
- {printf("Remember:\n\n A good user makes sure \"%s\"\n",SRC_FILE);
- printf(" is longer than %d charcters.\n",MIN_LENGTH);
- exit(20);
- }
-
- /* Output a wrapper to put round the phrase */
- printf("Remember:\n\n ");
-
- /* Now go look for a phrase in the file */
- do {
- /* Select somewhere in the middle of the file */
- where = rand() % length;
-
- /* Move there */
- fseek(fptr,where,SEEK_SET);
-
- /*
- Now move to the end of the prase we were in the middle of,
- then output the next phrase. If either function returns
- false then we hit the end of the data file and must go round
- and try again another place in the file.
- */
- } while (!find_next(fptr) || !out_next(fptr));
-
- /* Round the phrase off with a couple of newlines */
- puts("\n\n");
-
- #ifdef NORTHC
-
- if(_fromWB)
- {/* Wait for the user to hit a key before quitting the program */
- printf("Hit <Return>:");
- /* OK make sure that the last bit gets sent for buffered stdout */
- fflush(stdout);
- fgetc(stdin);
- }
-
- #endif
-
- /* Close the data file */
- fclose(fptr);
- }
-